﻿using System;
using System.Collections.Generic;
using Dict.Config;


namespace Battle.Engine.LogicModel
{
    public class FBuffManager
    {
        public List<Buff> buffs;
        public List<Buff> buffsOnce;//存储临时被清除的buff
        public List<Buff> onceCastbuffs;//每次攻击都要清除
        public List<Buff> onceHitbuffs;//每次命中计算都要清除

        public FActor actor;

        public FBuffManager(FActor actor)
        {
            this.actor = actor;
            this.buffs = new List<Buff>();
            this.buffsOnce = new List<Buff>();
            this.onceCastbuffs = new List<Buff>();
            this.onceHitbuffs = new List<Buff>();
        }

        public void Update(EngineData data)
        {//更新时间刷新的buff
            for (int i = 0; i < this.buffs.Count; i++)
            {
                if (buffs[i].Update(data))
                {
                    i--;
                }
            }

        }

        public int GetDebuffNum()
        {
            int debuffNum = 0;
            for (int i = 0; i < this.buffs.Count; i++)
            {
                if (buffs[i].isDebuff)
                {
                    debuffNum++;
                }
            }
            return debuffNum;
        }
        public void LoadSkillBuff(FSkillCast skillCast, FBuffTrigger trigger, TalentBuffTriggerTimer timer, FExportOnceData exportOnceData)
        {
            //判断buff概率是否生效
            double chanceperChange = 0;
            double chanceChange = 0;
            if (trigger.buffTemplate.isDebuff)
            {//获取目标降低负面buff的概率值
                chanceperChange = actor.attribute.minusDebuffperOdds;
                chanceChange = actor.attribute.minusDebuffOdds;
            }
            if (trigger.isActive(chanceperChange, chanceChange))
            {//buff概率随机生效
                var buff = trigger.buffTemplate.Clone();
                if (CanBuffCover(buff))
                {//先处理buff是否能被覆盖
                    buff.LoadBuff(actor, skillCast, timer, exportOnceData);
                }
            }
            
        }

        public void LoadSkillBuffBuff(FSkillCast skillCast, Buff buffTemplate, TalentBuffTriggerTimer timer, FExportOnceData exportOnceData)
        {
            var buff = buffTemplate.Clone();
            if (CanBuffCover(buff))
            {//先处理buff是否能被覆盖
                buff.LoadBuff(actor, skillCast, timer, exportOnceData);
            }
        }

        public void LoadTalentBuff(FTalent talent, FTalentBuff talentBuff, TalentBuffTriggerTimer timer, FExportOnceData exportOnceData)
        {
            //不能给自己人上debuff
            if (talent.actor.player.camp == actor.player.camp && talentBuff.buffTrigger.buffTemplate.isDebuff)
            {
                return;
            }
            //判断目标是否免疫该天赋
            if (actor.stateManager.IsImmuneTalentGroup(talent.group))
            {
                return;
            }
            //判断buff概率是否生效
            double chanceperChange = 0;
            double chanceChange = 0;
            if (talentBuff.buffTrigger.buffTemplate.isDebuff)
            {//获取目标降低负面buff的概率值
                chanceperChange = actor.attribute.minusDebuffperOdds;
                chanceChange = actor.attribute.minusDebuffOdds;
            }
            if (talentBuff.buffTrigger.isActive(chanceperChange, chanceChange))
            {//buff概率随机生效
                var buff = talentBuff.buffTrigger.buffTemplate.Clone();
                if (CanBuffCover(buff))
                {//先处理buff是否能被覆盖
                    buff.LoadBuff(actor, talent, timer, exportOnceData);
                }
            }

        }

        public void LoadTalentBuffBuff(FTalent talent, Buff buffTemplate, TalentBuffTriggerTimer timer, FExportOnceData exportOnceData)
        {
            //不能给自己人上debuff
            if (talent.actor.player.camp == actor.player.camp && buffTemplate.isDebuff)
            {
                return;
            }
            //判断目标是否免疫该天赋
            if (actor.stateManager.IsImmuneTalentGroup(talent.group))
            {
                return;
            }
            var buff = buffTemplate.Clone();
            if (CanBuffCover(buff))
            {//先处理buff是否能被覆盖
                buff.LoadBuff(actor, talent, timer, exportOnceData);
            }

        }

        public void LoadBuff(Buff buff, TalentBuffTriggerTimer timer, FExportOnceData exportOnceData)
        {
            if (buff.factor.Equals(TableFactorConst.reboundPerMaxhp))
            {
                if(buff.buffOrigion != null && buff.buffOrigion.GetSourceActor().isReboundBuff)
                {//复活buff已经被处理过了
                    return;
                }
            }
            buffs.Add(buff);
            if (buff.onceData)
            {
                if (timer == TalentBuffTriggerTimer.BeCastNotHit//被技能选中当还未计算命中时
                    || timer == TalentBuffTriggerTimer.AllHurt//被攻击时
                    || timer == TalentBuffTriggerTimer.NormalHurt//被普通攻击时
                    || timer == TalentBuffTriggerTimer.UltimateHurt//被特殊攻击时
                    || timer == TalentBuffTriggerTimer.Health//被技能治疗时
                    || timer == TalentBuffTriggerTimer.Dodge//闪避时
                    || timer == TalentBuffTriggerTimer.Hit//技能命中时
                    || timer == TalentBuffTriggerTimer.Cri//技能暴击时
                    || timer == TalentBuffTriggerTimer.BeCri//被技能暴击时
                    || timer == TalentBuffTriggerTimer.TeammateBeCri//友方受到暴击时
                    || timer == TalentBuffTriggerTimer.HpDown40InRound//回合内队友被技能攻击血量降低40%时
                    || timer == TalentBuffTriggerTimer.Block//格挡时
                    )
                {
                    onceHitbuffs.Add(buff);
                }
                else
                {
                    onceCastbuffs.Add(buff);
                }
                buff.Effect();
            }
            else if (buff.buffClass == BuffClass.DelayCreate)
            {//延迟生效 暂时不做处理

            }
            else
            {//非一次性的buff才往外传
                buff.Effect();
                if(exportOnceData != null)
                {
                    exportOnceData.loadBuffs.Add(buff);
                }
            }
        }

        public void UnLoadBuff(Buff buff)
        {
            buff.UnEffect();
            if (buff.onceData)
            {
                for (int i = 0; i < this.onceCastbuffs.Count; i++)
                {
                    if(this.onceCastbuffs[i].uniqueId == buff.uniqueId)
                    {
                        this.onceCastbuffs.Remove(buff);
                        break;
                    }
                }
                for (int i = 0; i < this.onceHitbuffs.Count; i++)
                {
                    if (this.onceHitbuffs[i].uniqueId == buff.uniqueId)
                    {
                        this.onceHitbuffs.Remove(buff);
                        break;
                    }
                }
            }
            else
            {
                //输出
                FExportOnceData exportOnceData = new FExportOnceData();
                exportOnceData.Init(buff);
                exportOnceData.unloadBuffs.Add(buff);
                this.actor.player.engineData.exports.Add(exportOnceData);
            }
            buffs.Remove(buff);
        }

        public void ProcMyRoundStart()
        {//处理自己回合开始时生效的buff
            for (int i = 0; i < this.buffs.Count; i++)
            {
                if (buffs[i].factor.Equals(TableFactorConst.poisonDam))
                {
                    FExportOnceData exportOnceData = new FExportOnceData();
                    exportOnceData.Init(buffs[i]);
                    this.actor.AddHp(-buffs[i].val, exportOnceData, HpInfSpecialType.poisonDam, AttackType.MAG);
                    this.actor.player.engineData.exports.Add(exportOnceData);
                }
                else if (buffs[i].factor.Equals(TableFactorConst.fireDam))
                {
                    FExportOnceData exportOnceData = new FExportOnceData();
                    exportOnceData.Init(buffs[i]);
                    this.actor.AddHp(-buffs[i].val, exportOnceData, HpInfSpecialType.fireDam, AttackType.MAG);
                    this.actor.player.engineData.exports.Add(exportOnceData);
                }
                else if (buffs[i].factor.Equals(TableFactorConst.recoverBySelfRound))
                {
                    FExportOnceData exportOnceData = new FExportOnceData();
                    exportOnceData.Init(buffs[i]);
                    this.actor.AddHp(buffs[i].val, exportOnceData, HpInfSpecialType.Recover, AttackType.PHY);
                    this.actor.player.engineData.exports.Add(exportOnceData);
                }
                else if (buffs[i].factor.Equals(TableFactorConst.additionAttBySelfRound))
                {
                    for(int s = 0; s < buffs[i].args3; s++)
                    {//额外攻击 减血=(攻击+物法攻击-目标物法防御)*额外攻击系数*(1+伤害加成-目标伤害减免-目标物法伤害减免)
                        FExportOnceData exportOnceData = new FExportOnceData();
                        exportOnceData.Init(buffs[i]);
                        //获取目标
                        List<SelectLimitCondition> limitConditions = this.actor.player.engineData.LimitConditions(true, true, true); ;
                        List<FActor> targets = this.actor.player.engineData.SelectTargetActors(false, (int)buffs[i].args2, buffs[i].buffTargetActor, null, limitConditions);
                        foreach (var target in targets)
                        {
                            double att = buffs[i].buffTargetActor.attribute.att.value;
                            double attAdd = buffs[i].buffTargetActor.attackType == AttackType.PHY ? buffs[i].buffTargetActor.attribute.patt.value : buffs[i].buffTargetActor.attribute.matt.value;
                            double def = buffs[i].buffTargetActor.attackType == AttackType.PHY ? target.attribute.pdef.value : target.attribute.mdef.value;
                            double damageAdd = buffs[i].buffTargetActor.attribute.damageAdd;
                            double damageReduce = target.attribute.damageReduce;
                            double damageReduceAdd = buffs[i].buffTargetActor.attackType == AttackType.PHY ? target.attribute.pdamageReduce : target.attribute.mdamageReduce;
                            double damage = (1 + damageAdd - damageReduce - damageReduceAdd) < 0 ? 0 : (1 + damageAdd - damageReduce - damageReduceAdd);
                            double totalDamage = (att + attAdd - def) * buffs[i].args1 * CommonMethod.tableAttributeConvert * damage;
                            if(totalDamage < 1)
                            {
                                totalDamage = 1;
                            }
                            target.AddHp(-totalDamage, exportOnceData, HpInfSpecialType.AdditionAtt, buffs[i].buffTargetActor.attackType);
                        }
                        this.actor.player.engineData.exports.Add(exportOnceData);
                    }
                }
                else if (buffs[i].factor.Equals(TableFactorConst.permaxHpBySelfRound))
                {
                    FExportOnceData exportOnceData = new FExportOnceData();
                    exportOnceData.Init(buffs[i]);
                    this.actor.AddHp(buffs[i].val, exportOnceData, HpInfSpecialType.Buff, AttackType.PHY);
                    this.actor.player.engineData.exports.Add(exportOnceData);
                }
            }
        }

        public void ProcMyRoundEnd()
        {//处自己回合结束后，死亡
            for (int i = 0; i < this.buffs.Count; i++)
            {
                if (buffs[i].factor.Equals(TableFactorConst.dieAfterLastAttack))
                {
                    FExportOnceData exportOnceData = new FExportOnceData();
                    exportOnceData.Init(buffs[i]);
                    this.actor.DoDead(this.actor.player.engineData, exportOnceData);
                    this.actor.player.engineData.exports.Add(exportOnceData);
                }
            }
        }

        public void RoundEnd()
        {
            for (int i = 0; i < this.buffs.Count; i++)
            {
                if (this.buffs[i].minusRound())
                {
                    i--;
                }
            }
        }
        
        public void ProcAttEnd()
        {
            for (int i = 0; i < this.buffs.Count; i++)
            {
                if (this.buffs[i].minusAttCount())
                {
                    i--;
                }
            }
        }

        public void ProcDefEnd()
        {
            for (int i = 0; i < this.buffs.Count; i++)
            {
                if (this.buffs[i].minusDefCount())
                {
                    i--;
                }
            }
        }

        public bool CanBuffCover(Buff buff)
        {
            //判断目标是否免疫该buff
            if (actor.stateManager.IsImmuneBuffGroup(buff.group))
            {
                return false;
            }
            if (actor.stateManager.IsImmuneBuff(buff))
            {
                return false;
            }
            if (buff.factor.Equals(TableFactorConst.reliveAndinvisible) && this.actor.isRelive)
            {//重生的buff只生效一次
                return false;
            }
            if (buff.shouldCover)
            {//对于需要进行覆盖的buff，先比对原有buff
                for (int i = 0; i < buffs.Count; i++)
                {
                    if (!buff.group.Equals("") && buffs[i].group.Equals(buff.group))
                    {
                        if (buffs[i].type.Equals(TableFactorConst.shield))
                        {//由于血盾的数值会发生改变，则以实际数值为准
                            if (actor.attribute.shield < buffs[i].val)
                            {//原有buff效果小于新增buff，则删除原有buff
                                buffs[i].UnloadBuff();
                                return true;
                            }
                        }
                        else if (buffs[i].type.Equals(TableFactorConst.pshield))
                        {//由于血盾的数值会发生改变，则以实际数值为准
                            if (actor.attribute.pshield < buffs[i].val)
                            {//原有buff效果小于新增buff，则删除原有buff
                                buffs[i].UnloadBuff();
                                return true;
                            }
                        }
                        else if (buffs[i].type.Equals(TableFactorConst.mshield))
                        {//由于血盾的数值会发生改变，则以实际数值为准
                            if (actor.attribute.mshield < buffs[i].val)
                            {//原有buff效果小于新增buff，则删除原有buff
                                buffs[i].UnloadBuff();
                                return true;
                            }
                        }
                        else
                        {
                            if (buffs[i].args1 < buff.args1)
                            {//原有buff效果小于新增buff，则删除原有buff
                                buffs[i].UnloadBuff();
                                return true;
                            }
                        }
                        return false;
                    }
                }
                //没有比对到同类冲突的buff数据，可直接做累加
                return true;
            }
            else if (buff.totalCount > 0)
            {//累加次数限制
                int count = 0;
                for (int i = 0; i < buffs.Count; i++)
                {
                    if (buffs[i].id.Equals(buff.id))
                    {
                        count++;
                    }
                }
                if(count >= buff.totalCount)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            else
            {
                return true;
            }
        }

        public void uneffectBuffsOnce()
        {
            foreach(var buff in this.buffs)
            {
                //能被清除的buff暂时不生效
                if(buff.isDebuff == false && buff.canBeCleared == true)
                {
                    buff.UnEffect();
                    this.buffsOnce.Add(buff);
                }
            }
        }

        public void reeffectBuffsOnce()
        {
            foreach (var buff in this.buffsOnce)
            {
                buff.Effect();
            }
            buffsOnce.Clear();
        }

        public void removeShieldBuff()
        {
            for (int i = 0; i < buffs.Count; i++)
            {
                if (buffs[i].factor.Equals(TableFactorConst.shield)
                    || buffs[i].factor.Equals(TableFactorConst.sourceperattToshield))
                {//清除血盾buff
                    buffs[i].UnloadBuff();
                    i--;
                }
            }
        }
        public void removePShieldBuff()
        {
            for (int i = 0; i < buffs.Count; i++)
            {
                if (buffs[i].factor.Equals(TableFactorConst.sourceperattTopshield))
                {//清除物理血盾buff
                    buffs[i].UnloadBuff();
                    i--;
                }
            }
        }
        public void removeMShieldBuff()
        {
            for (int i = 0; i < buffs.Count; i++)
            {
                if (buffs[i].factor.Equals(TableFactorConst.sourceperattTomshield))
                {//清除魔法血盾buff
                    buffs[i].UnloadBuff();
                    i--;
                }
            }
        }

        public void Dispel(bool isDebuff, int num = 0)
        {
            List<Buff> selectBuffs = new List<Buff>();
            for (int i = 0; i < buffs.Count; i++)
            {
                if (buffs[i].canBeCleared && buffs[i].isDebuff == isDebuff)
                {//选择能被清除的buff或者debuff
                    selectBuffs.Add(buffs[i]);
                }
            }
            if (num == 0)
            {//默认清除所有
                for (int i = 0; i < selectBuffs.Count; i++)
                {
                    selectBuffs[i].UnloadBuff();
                }
            }
            else
            {//随机清除num个
                for (int i = 0; i < num; i++)
                {
                    if(selectBuffs.Count > 0)
                    {
                        int randomIndex = this.actor.player.engineData.random.Range(0, selectBuffs.Count);
                        var selectBuff = selectBuffs[randomIndex];
                        selectBuffs.Remove(selectBuff);
                        selectBuff.UnloadBuff();
                    }
                }
            }
        }
        /// <summary>
        /// 一次性的buff需要在每次buff处理前进行清除
        /// </summary>

        public void ClearOnceCastBuff()
        {
            while (this.onceCastbuffs.Count > 0)
            {
                this.onceCastbuffs[this.onceCastbuffs.Count-1].UnloadBuff();
            }
        }

        public void ClearOnceHitBuff()
        {
            while (this.onceHitbuffs.Count > 0)
            {
                this.onceHitbuffs[this.onceHitbuffs.Count-1].UnloadBuff();
            }
        }
        
        //死亡时清除所有buff
        public void ClearAllBuff()
        {
            reeffectBuffsOnce();
            ClearOnceCastBuff();
            ClearOnceHitBuff();
            while (this.buffs.Count > 0)
            {
                this.buffs[this.buffs.Count - 1].UnloadBuff();
            }
        }
    }
}
